python+tesseract 训练和破解验证码

您所在的位置:网站首页 pytesseract module python+tesseract 训练和破解验证码

python+tesseract 训练和破解验证码

2023-02-25 10:18| 来源: 网络整理| 查看: 265

本文介绍了一种高效破解验证码的方法,主要针对彩色背景,包含数字和英文字母,有干扰线的简单验证码。

一、使用技术window 10python 3.6tesseract-ocr.exejTessBoxEditor-1.8.0 #用来完成tesseract字库的训练requests, pytesseract, PIL包二、流程介绍环境配置验证码图片下载验证码图片处理基于验证码中字符的tesseract字库训练验证码破解三、环境配置python 3.6的安装及配置

入门python第一步就是这个,相信大多数人都会。具体方法可以参考https://blog.csdn.net/nerissa_lou/article/details/78300839

2. tesseract-ocr的安装和配置

Tesseract是一个由HP公司开发(后由Google接手)的开源的OCR(Optical Character Recognition,光学字符识别)引擎,可以识别多种格式的图像文件并将其转换成文本,目前已支持多种语言(包括中文)。

tesseract-ocr的具体安装和环境变量配置方法可以参考我的CSDN博客:

3. jTessBoxEditor-1.8.0的安装和使用

jTessBoxEditor是训练tesseract词库的一款工具,可以直接从官网下载压缩包,下载地址Browse /jTessBoxEditor at SourceForge.net。解压后,可直接使用。但是这个工具是用java开发的,需要jre7以上的版本支持。

此外, jTessBoxEditor解压包中自带了一个tesseract-ocr文件包。我们需要使用第二步中自己安装tesseract-ocr生成的文件覆盖掉jTessBoxEditor\tesseract-ocr\中的文件。

4. urllib, pytesseract, PIL包的安装

urllib包是python 3.6 自带的, 这里主要是使用urllib.request.urlretrieve 函数来从网页上下载图片到本地。

pytesseract是python操作tesseract-ocr的一个api。PIL是python中图片处理使用的包。这两个包可以直接通过pip install 进行安装。

四、验证码图片下载

验证码图片我是从蘑菇ip代理网站登录页面下载下来的。URL为http://www.moguproxy.com/proxy/validateCode/createCode?time=1532067398380。其中,最后面是一个时间戳。通过改变这个时间戳的值,生成300个url,向它们发送请求,获取验证码图片。

具体代码如下:

import random from urllib.request import urlretrieve import os #下载300张验证码图片 url = 'http://www.moguproxy.com/proxy/validateCode/createCode?time={}' path = os.path.dirname(__file__) + '/origin_imgs/' #将下载的图片保存到当前目录下的origin_imgs文件夹中 for i in range(1531878604000,1531878604300): urlretrieve(url.format(i), path + str(i)[-3:] + '.jpg') print('成功下载 {} 张图片'.format(str(i)[-3:]))

下载后的结果如下图所示:

图1. 验证码图片集合

五、验证码图片处理

由上图可以看出,这种验证码图片背景为彩色,包含大小写英文字母和数字,每个字符的颜色都不相同,少数字符还紧贴着彼此,此外图片中还存在着多条不同颜色的干扰线。直接使用pytesseract对它们进行识别,识别成功率是很低的。所以需要对图片进行一定的预处理。

这里我们通过颜色提取的方法,一步实现了抛去背景和干扰线,字符分离的目的。具体预处理过程见代码:

from PIL import Image import os path = os.path.dirname(__file__) origin_path = path + '/origin_imgs/' new_path = path + '/clean_imgs/' #用来存放处理好的图片 #从100张图片中提取出字符样本 for image in os.listdir(origin_path)[:100]: im = Image.open(origin_path+image) width, height = im.size #获取图片中的颜色,返回列表[(counts, color)...] color_info = im.getcolors(width*height) #按照计数从大到小排列颜色,那么颜色计数最多的应该是背景,接下来排名2到6的则对应5个字符。 sort_color = sorted(color_info, key=lambda x: x[0], reverse=True) #根据颜色,提取出每一个字符,重新放置到一个新建的白色背景image对象上。每个image只放一个字符。 char_dict = {} for i in range(1, 6): im2 = Image.new('RGB', im.size, (255, 255, 255)) for x in range(im.size[0]): for y in range(im.size[1]): if im.getpixel((x, y)) == sort_color[i][1]: im2.putpixel((x, y), (0, 0, 0)) else: im2.putpixel((x, y), (255, 255, 255)) im2.save(new_path + str(i)+'-'+ image.replace('jpg','tif')) print('成功处理图片{}'.format(image))

处理后的结果如下图所示:

图2. 处理后的验证码图片

此时如果用pytesseract对图2中所示的图片进行识别:

for image in os.listdir(new_path): im2 = Image.open(new_path+image) char = pytesseract.image_to_string(im2, config='--psm 10') # psm 10表示将图片识别成单个字符。 print(char)

大部分的字符都可以被正确识别,但是还是有许多不足,例如,不能识别a, b, d, p,q,会把o和O识别成0, z和Z识别成2。

针对这种情况,只能使用jTessBoxEditor来手动建立tesseract的训练集,将不能正确识别的字符添加进去。

六、使用jTessBoxEditor建立训练集

因为所有字符集合其实是26个小写字母+26个大写字母+0到9数字,共62个字符。且每个字符的书写都是一样的,所以从处理后的图片中每个字符挑出一张图片,放入char_imgs文件夹中。

合并char_imgs中的图片

打开jTessBoxEditor, 点击Tools,选择Merge TIFF, 进入char_imgs目录下,全选所有图片,点击打开。然后将merge(合并)后的文件保存在同目录下,名称为mjchar.tif:

2. 生成mjchar.box文件

打开cmd, 切换到char_imgs目录下,执行tesseract命令:

tesseract mjchar.tif mjchar -psm 10 batch.nochop makebox

运行结果如下,同时char_imgs目录下生成了一个mjchar.box文件。

3. 校正字符集

用 jTessBoxEditor打开生成的图片集 mjchar.tif ,注意 mjchar.tif 与对应的box文件一定要处于同一个文件夹下,然后就可以开始调整了(记得要翻页),调整完之后保存。

4. 训练

首先在char_imgs目录下新建一个名字为“font_properties”的文本文件,并且输入文本 normal 0 0 0 0 0,表示非斜体,粗体的一般字体。

执行 tesseract mjchar.tif mjchar nobatch box.train 进行测试训练。

执行 unicharset_extractor mjchar.box, char_imgs目录下生成一个名为unicharset的文件。

执行 shapeclustering -F font_properties.txt -U unicharset mjchar.tr, char_imgs目录下生成一个名为mjchar.tr的文件

执行 mftraining -F font_properties.txt -U unicharset -O unicharset mjchar.tr

执行 cntraining mjchar.tr

此时char_imgs目录下生成了5个文件:

在这五个文件前加上normal.进行重命名:

执行 combine_tessdata normal, 合并五个文件,此时目录下的normal.traineddata 就是训练好的字库文件。

把normal.traineddata 复制到Tesseract-OCRt程序目录下的“tessdata”目录:

至此,词库训练就完成了。接下来使用pytesseract再去识别处理好的验证码,语言选择normal(即刚训练好的词库),识别成功率接近百分百。

char = pytesseract.image_to_string(im2, lang='normal',config='--psm 10')

七、在线验证码破解完整代码import requests from PIL import Image import pytesseract from io import BytesIO headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'} captcha_url = 'http://www.moguproxy.com/proxy/validateCode/createCode?time={} '.format(int(time.time() * 1000)) r = requests.get(captcha_url, headers=headers) #请求验证码图片链接 im = Image.open(BytesIO(r.content)) #直接读取bytes数据,生成图片对象 width, height = im.size #获取图片中的颜色,返回列表[(counts, color)...] color_info = im.getcolors(width*height) sort_color = sorted(color_info, key=lambda x: x[0], reverse=True) #将背景全部改为白色, 提取出字,每张图片一个字 char_dict = {} for i in range(1, 6): start_x = 0 im2 = Image.new('RGB', im.size, (255, 255, 255)) for x in range(im.size[0]): for y in range(im.size[1]): if im.getpixel((x, y)) == sort_color[i][1]: im2.putpixel((x, y), (0, 0, 0)) if not start_x: start_x = x #标记每个字符的起始位置,用于最后字符串的排序 else: im2.putpixel((x, y), (255, 255, 255)) char = pytesseract.image_to_string(im2, lang='normal',config='--psm 10') char_dict[start_x] = char code = ''.join([item[1] for item in sorted(char_dict.items(), key=lambda i:i[0])]) print(code)

八、结语

以上就是使用python+tesseract识别彩色字母数字验证码的全部过程。通过对验证码的处理(根据颜色计数提取字符)和tesseract词库的训练,基本可以正确识别全部英文字母和数字。这种方法对于识别类似情况的中文验证码也是可以的。

自己摸着石头一步一步实现了整个过程,记录下来加深印象,也希望可以帮助到有需要的朋友。

谢谢!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3